// 实现这个项目的构建任务
const { src, dest, parallel, series, watch } = require('gulp')

const del = require('del')
const browserSync = require('browser-sync')
var ghpages = require('gh-pages');

const loadPlugins = require('gulp-load-plugins')
const minimist = require('minimist')
const csscomb = require('csscomb'); // css编码风格格式化
const standard = require('standard'); // js编码风格格式化


const plugins = loadPlugins()
const bs = browserSync.create()
const cwd = process.cwd();
let config = {
  //default config
  build:{
    src:'src',
    dist: 'dist',
    temp: 'temp',
    public: 'public',
    paths:{
      styles:'assets/styles/*.scss',
      scripts:'assets/scripts/*.js',
      pages:'*.html',
      images:'assets/images/**',
      fonts:'assets/fonts/**',
    }
  }
}

// 解析命令行选项
const args = minimist(process.argv.slice(2));

const bsInit = {
  notify: false,
  port: args.port || 2080,
  open: args.open || false,
};

// const data = 是

try{
  const loadConfig = require(`${cwd}/pages.config.js`);
  config = Object.assign({},config,loadConfig)
} catch (err){

}


const clean = () => {
  return del([config.build.dist, config.build.temp])
}

const style = () => {
  return src(config.build.paths.styles, { base:  config.build.src ,cwd: config.build.src})
    .pipe(plugins.sass({ outputStyle: 'expanded' }))
    .pipe(dest(config.build.temp))
    .pipe(bs.reload({ stream: true }))
}

const script = () => {
  return src(config.build.paths.scripts, { base:  config.build.src , cwd: config.build.src })
    .pipe(plugins.babel({ presets: [require('@babel/preset-env')] }))
    .pipe(dest(config.build.temp))
    .pipe(bs.reload({ stream: true }))
}

const page = () => {
  return src(config.build.paths.pages, { base:  config.build.src , cwd: config.build.src })
    .pipe(plugins.swig({ data: config.data, defaults: { cache: false } })) // 防止模板缓存导致页面不能及时更新
    .pipe(dest(config.build.temp))
    .pipe(bs.reload({ stream: true }))
}

const image = () => {
  return src(config.build.paths.images, { base:  config.build.src , cwd: config.build.src })
    .pipe(plugins.imagemin())
    .pipe(dest(config.build.dist))
}

const font = () => {
  return src(config.build.paths.fonts, { base:  config.build.src , cwd: config.build.src })
    .pipe(plugins.imagemin())
    .pipe(dest(config.build.dist))
}

const extra = () => {
  return src('**', { base: config.build.public, cwd: config.build.public })
    .pipe(dest(config.build.dist))
}

const serve = () => {
  watch(config.build.paths.styles, {cwd: config.build.src},style)
  watch(config.build.paths.scripts,{cwd: config.build.src}, script)
  watch(config.build.paths.scripts,{cwd: config.build.src}, page)
  watch([
    config.build.paths.images,
    config.build.paths.fonts,
  ],{cwd: config.build.src}, bs.reload)

  watch("**",{cwd: config.build.public}, bs.reload)

  bs.init({
    ...bsInit,
    // open: false,
    // files: 'dist/**',
    server: {
      baseDir: [config.build.temp, config.build.src, config.build.public],
      routes: {
        '/node_modules': 'node_modules'
      }
    }
  })
}
//start命令开启的服务  以生产模式运行  目录则为dist
const startServe = () => {
  bs.init({
    ...bsInit,
    // open: false,
    // files: 'dist/**',
    server: {
      baseDir: [config.build.dist],
    }
  })
}




const useref = () => {
  return src('temp/*.html', { base: config.build.temp })
    .pipe(plugins.useref({ searchPath: [config.build.temp, '.'] }))
    // html js css
    .pipe(plugins.if(/\.js$/, plugins.uglify()))
    .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
    .pipe(plugins.if(/\.html$/, plugins.htmlmin({
      collapseWhitespace: true,
      minifyCSS: true,
      minifyJS: true
    })))
    .pipe(dest(config.build.dist))
}


const publish = done =>{
  if(!config.build.giturl){
    done(new Error("请在根目录pages.config.js中配置giturl 地址"))
    return;
  }
  ghpages.publish('dist', {
    branch: args.production || 'gh-pages',
    repo: config.build.giturl
  }, function(err) {
    if(err){
      done(new Error(err))
    }else{
      done()
    }
  });
}



const styleLint = done => {
  const css = new csscomb(require('./.csscomb.json'));
  css.processPath(config.build.paths.styles);
  done();
}

const scriptLint = done => {
  standard.lintFiles(config.build.paths.scripts, { cwd: `${cwd}/src/`, fix: true }, done);
}

const lint = parallel(styleLint,scriptLint)

const outlog = done => {
  console.log(process.argv)
  console.log(minimist(process.argv.slice(2)))
  done();
}

const compile = parallel(style, script, page)

// 上线之前执行的任务
const build =  series(
  clean,
  parallel(
    series(compile, useref),
    image,
    font,
    extra
  )
)

const develop = series(compile, serve)

//start 命令之前需要先build

const start = series(build,startServe);

const deploy = series(build,publish)

module.exports = {
  clean,
  build,
  "serve":develop,
  outlog: outlog,
  start,
  deploy,
  lint
}
